package com.mukefile.dao.impl;

import com.mukefile.dao.UserFileDao;
import com.mukefile.dto.DeleteFileDto;
import com.mukefile.pojo.UserFile;
import com.mukefile.pojo.UserFolder;
import com.mukefile.utils.constant.Constant;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.query.NativeQuery;
import org.hibernate.query.Query;
import org.springframework.orm.hibernate5.HibernateCallback;
import org.springframework.orm.hibernate5.HibernateTemplate;
import org.springframework.stereotype.Repository;

import javax.annotation.Resource;
import java.math.BigInteger;
import java.util.List;
import java.util.Objects;

/**
 * @author xinke.huang@hand-china.com
 * @version 1.0
 * @date 2021/2/10
 */
@Repository
public class UserFileDaoImpl implements UserFileDao {
    @Resource
    HibernateTemplate hibernateTemplate;

    @Override
    public int insertFolder(UserFolder folder) {
        hibernateTemplate.saveOrUpdate(folder);
        return 1;
    }

    @Override
    public void updateFolderName(UserFolder folder) {

        String sql = "update muke_user_folder set folder_name=?,update_time=? where id=?";
        Session session = hibernateTemplate.getSessionFactory().getCurrentSession();
        Query query = session.createSQLQuery(sql);
        query.setParameter(1,folder.getFolderName());
        query.setParameter(2,folder.getUpdateTime());
        query.setParameter(3,folder.getId());
        int i = query.executeUpdate();
    }

    @Override
    public void updateFileName(UserFile file) {
        String sql = "update muke_user_file set filename=?,update_time=? where id=?";
        Session session = hibernateTemplate.getSessionFactory().getCurrentSession();
        Query query = session.createSQLQuery(sql);
        query.setParameter(1,file.getFilename());
        query.setParameter(2,file.getUpdateTime());
        query.setParameter(3,file.getId());
        int i = query.executeUpdate();
    }

    @Override
    public List<Object[]> selectAllFolderAndFile(Integer userId,Long pid ,Integer limitStart, Integer limitEnd) {
        String sql = "(SELECT\n" +
                "\tfolder.id id,\n" +
                "\tfolder.folder_name name,\n" +
                "\tfolder.parent_folder_id pid,\n" +
                "\tfolder.update_time,\n" +
                "\tfolder.type,\n" +
                "  null\tsize\n" +
                "FROM \n" +
                "\tmuke_user_folder folder\n" +
                "WHERE \n" +
                "\tfolder.deleted='N' AND \n" +
                "\tfolder.parent_folder_id = ? AND\n" +
                "\tfolder.user_id=?)\n" +
                "UNION\n" +
                "(SELECT\n" +
                "\tfile.id id,\n" +
                "\tfile.filename name,\n" +
                "\tfile.folder_id pid,\n" +
                "\tfile.update_time,\n" +
                "\tfile.type,\n" +
                "\tactual.file_byte size\n" +
                "FROM \n" +
                "\tmuke_user_file file,\n" +
                "\tmuke_actual_file actual\n" +
                "WHERE \n" +
                "\tfile.deleted='N' AND\n" +
                "\tfile.user_id=? AND\n" +
                "\tfile.folder_id = ? AND\n" +
                "\tactual.id=file.actual_id)\n" +
                "ORDER BY type DESC,update_time DESC\n" +
                "LIMIT ?,?";

        return  (List<Object[]>) hibernateTemplate.execute(session -> {
            Query query = session.createSQLQuery(sql);
            query.setParameter(1,pid);
            query.setParameter(2,userId);
            query.setParameter(3,userId);
            query.setParameter(4,pid);
            query.setParameter(5,limitStart);
            query.setParameter(6,limitEnd);
            List list = query.list();
            return list;
        });
    }

    @Override
    public long selectFolderAndFileCount(Integer userId ,Long pid) {
        String sql = "SELECT (file.num1+folder.num2) num FROM\n" +
                "(SELECT count(id) num1 FROM muke_user_file WHERE deleted='N' AND user_id=? AND folder_id=?) file,\n" +
                "(SELECT count(id) num2 FROM muke_user_folder WHERE deleted='N' AND user_id=? AND parent_folder_id=?) folder";
        List execute = hibernateTemplate.execute(session -> {
            Query query = session.createSQLQuery(sql);
            query.setParameter(1, userId);
            query.setParameter(2,pid);
            query.setParameter(3, userId);
            query.setParameter(4,pid);
            List list = query.list();
            return list;
        });
        return ((BigInteger)execute.get(0)).longValue();
    }

    @Override
    public UserFolder selectFolderById(Long id) {
        Session session = hibernateTemplate.getSessionFactory().openSession();
        return session.get(UserFolder.class, id);
    }

    @Override
    public UserFile selectUserFileById(Long id) {
        return hibernateTemplate.get(UserFile.class,id);
    }

    @Override
    public void batchUpdateFiles(List<DeleteFileDto> list,String deleted) {
        if (list.size() == 0){
            return;
        }
        StringBuilder sql = new StringBuilder("update muke_user_file set deleted=? where id in (");
        for (DeleteFileDto dto : list){
            sql.append("?,");
        }
        sql.setCharAt(sql.length()-1,')');
        Session session = hibernateTemplate.getSessionFactory().getCurrentSession();
        Query query = session.createSQLQuery(sql.toString()).setParameter(1,deleted);
        int i = 2;
        for (DeleteFileDto fileDto:list){
            query.setParameter(i,fileDto.getId());
            i++;
        }
        query.executeUpdate();
    }
}
